<template>
  <div class="dynamic_table_item">
    <template v-if="props.question.type === 'search'">
      <a-select
        v-model:value="localValue"
        showSearch
        :allowClear="props.question.state.allowClear === false?false:true"
        :placeholder="props.question.placeholder || '请输入'"
        :getPopupContainer="hangBody"
        style="width: 100%"
        :mode="props.question.state.mode"
        :placement="props.question.state?.placement || 'bottomLeft'"
        :filter-option="false"
        :not-found-content="state.fetching ? undefined : null"
        :options="state.data"
        @search="fetchUser"
        @popupScroll="handlePopupScroll"
        @change="(value, option) => selectQs({ key: props.question.key, value, option })"
      >
        <template v-if="state.fetching" #notFoundContent>
          <a-spin size="small" />
        </template>
      </a-select>
    </template>
    <!-- 自动完成输入 -->
    <template v-else-if="props.question.type === 'auto'">
      <a-auto-complete
        v-model:value="localValue"
        :getPopupContainer="hangBody"
        :allowClear="props.question.state.allowClear === false?false:true"
        :placeholder="props.question.placeholder || '请输入'"
        :disabled="isDisabled()"
        style="width: 100%"
        :filter-option="false"
        :options="state.data"
        @search="fetchUser"
        @popupScroll="handlePopupScroll"
        @change="(value) => selectQs({ key: props.question.key, value })"
      >
      </a-auto-complete>
    </template>
    <template v-else-if="props.question.type === 'tree'">
      <a-tree-select
        v-model:value="localValue"
        :getPopupContainer="hangBody"
        @change="(value, option) => selectQs({ key: props.question.key, value, option })"
        :allowClear="props.question.state.allowClear === false?false:true"
        show-search
        style="width: 100%"
        :multiple="props.question.state.multiple"
        :placement="props.question.state?.placement || 'bottomLeft'"
        :placeholder="props.question.placeholder || '请输入'"
        :tree-default-expand-all="props.question.state.expandAll || false"
        :tree-node-filter-prop="fieldNames.title || 'label'"
        :fieldNames="fieldNames"
        :load-data="props.question.state.loadData ? onLoadData : null"
        :disabled="isDisabled()"
        :tree-data="props.question.options"
        :tree-checkable="props.question.state.treeCheckable"
      />
    </template>
    <template v-else>
      <a-select
        :mode="props.question.state.mode || ''"
        :getPopupContainer="hangBody"
        :showSearch="props.question.state?.showSearch"
        style="width: 100%"
        :allowClear="props.question.state.allowClear === false?false:true"
        max-tag-count="responsive"
        :placement="props.question.state?.placement || 'bottomLeft'"
        :optionFilterProp="props.question.state?.optionFilterProp || 'value'"
        v-model:value="localValue"
        :placeholder="props.question.placeholder || '请输入'"
        :virtual="false"
        @popupScroll="handlePopupScroll"
        @change="(value, option) => selectQs({ key: props.question.key, value, option })"
        :disabled="isDisabled()"
      >
        <a-select-option v-for="item in props.question.options" :label="item.label" :key="item.value" :value="item.value">
          {{ item.label }}
        </a-select-option>
      </a-select>
    </template>
  </div>
</template>

<script setup lang="ts">
import { watch, getCurrentInstance, onMounted, onUnmounted, ref, reactive, computed } from 'vue';
import { filter } from 'rxjs/operators';
import { Subscription } from 'rxjs';
// import dictionary from '@/filters/dictionary';
import { INFOSERVE, INITSERVE, RESETVERIFY, SELECTSERVE } from '@/mixins/subject/subject-types';
import { formInfoStore } from '@/store/modules/form';
import { debounce } from 'lodash-es';
import { getDictionaryList } from '@/utils/dictionary';
import { assignParams, paramsData,showKeyName } from '@/components/public-template/publicMethod';
import localDictionary from "@/filters/dictionary";
import { isHidden } from '@/utils';
const formStore = formInfoStore();
let dictionary = formStore.getDictionary;

//挂在body
const hangBody = ()=>{
  let idName = import.meta.env.VITE_PUBLIC_PATH.split('/').find(res=>res.includes('-')).split('-')[0] + 'Storage';
  return idName ? document.getElementById(idName) : document.body
}

//subject变量
let $subscribeSub: Subscription;

const { proxy }: any = getCurrentInstance();
let props = defineProps<{ question: any; formData: any ;dataForm:any;index?:any}>();
const emit = defineEmits(['update:formData']);
const state = reactive({
  data: [],
  fetching: false
});
let lastFetchId = 0;

const localValue:any = ref(null);
const fieldNames: any = ref(
  props.question.state.fieldNames
    ? props.question.state.fieldNames
    : {
        children: props.question.state.nameChildren ? props.question.state.nameChildren : 'children',
        title: props.question.state.nameChildren ? props.question.state.nameKey : 'label',
        key: props.question.state.nameChildren ? props.question.state.nameValue : 'id'
      }
);

watch(
  () => localValue.value,
  (val) => {
    state.fetching = false;
    emit('update:formData', val);
  },
  { flush: 'sync' }
);
watch(
  () => props.formData,
  (val) => {
    if( props.formData !==  localValue.value){
      localValue.value = props.formData;
    }
  },
  { flush: 'sync' }
);

onMounted(() => {
  subWatch();
  init();
  // 防止多次请求
  if( props.question.type === 'search' && !props.question.state.updateOption ){
    fetchUser();
  }
});

//解绑
onUnmounted(() => {
  if ($subscribeSub != undefined) {
    $subscribeSub.unsubscribe();
  }
});

//是否禁用
const isDisabled = ()=>{
  let disabled:boolean = false;
  if( Array.isArray(props.question.disabled)){
    disabled = isHidden(props.dataForm, { showKey: props.question.disabled });
    if( props.question.invertDisabled ){
      disabled = !disabled;
    }
  }else if( typeof props.question.disabled === 'boolean'  ){
    return props.question.disabled
  }
  return disabled
}

//静态数据
const staticView = computed(() => {
  if (props.question.value || props.question.value == 0) {
    if( Array.isArray(props.question.value) ){
      let names = props.question.options.filter(res=>props.question.value.includes(res.value));
      if( names && names.length ){
        return names.map(res=>res.label).join(',')
      }
    }else{
      let data = props.question.options.find((res) => res.value === props.question.value);
      if (data) {
        return data.label;
      }
    }
  }
});


//搜索
const fetchUser = debounce((value:any = null) => {
  lastFetchId += 1;
  const fetchId = lastFetchId;
  state.fetching = true;
  let params = {};
  if(props.question.state.popupScroll){
    params = Object.assign({},pagination)
    pagination.pageNumber++;
  }else{
    state.data = [];
  }
  params = Object.assign(params,
    props.question.state.params || {}
  );
  if( value && value !== 0  ){
    params[props.question.state.nameKey || props.question.key] = value;
  }
  proxy.$Http.api(props.question.state.url, params, props.question.state.protType ? props.question.state.protType : 'get').then((res) => {
    if (res) {
      if (fetchId !== lastFetchId) {
        // for fetch callback order
        return;
      }
      let data = res?.data?.map((data: any) => ({
        label: data[props.question.state.nameKey],
        value: data[props.question.state.nameValue],
        ...data
      }));
      if( props.question.state.popupScroll ){
        state.data.push(...data);
      }else{
        state.data = data;
      }
      props.question.options = state.data;
      state.fetching = false;
      loadingOptions.value = false;
      console.log('options', state.data);
    }
  });
}, 300);


//滚动自动分页
//分页参数
let pagination: any = reactive({
  pageNumber: 1,
  pageSize: 50,
});
const loadingOptions = ref(false);
const handlePopupScroll = async (e) => {
  if(!props.question.state.popupScroll){
    return
  }
  if (e.target && e.target.scrollTop + e.target.clientHeight +30 >= e.target.scrollHeight) {
    console.log('到底了');
    if (!loadingOptions.value) {
      loadingOptions.value = true;
      if( props.question.type === 'search' ||  props.question.type === 'auto'){
        fetchUser(localValue);
      }else{
        getOptions();
      }
    }
  }
};

//接口获取options
const getOptions = debounce((fn:any = null)=>{
  let params = {};
  if(props.question.state.popupScroll){
    params = Object.assign({},pagination)
  }
  params = Object.assign(params, props.question.state.params || {}, props.question.state.assign || {});
    proxy.$Http.api(props.question.state.url, params, props.question.state.protType ? props.question.state.protType : 'get').then((res) => {
      if (res) {
        // // 递归children
        pagination.pageNumber++;
        let data = reData(res.data);
        if( props.question.state.popupScroll ){
          props.question.options.push(...data);
        }else{
          props.question.options = data;
        }
        state.data = props.question.options;
        if( fn ){
          fn()
        }
      }
      loadingOptions.value = false;
    });
},300)



//动态加载
const onLoadData = (treeNode) => {
  return new Promise((resolve) => {
    if (treeNode.dataRef[fieldNames.value.children]) {
      resolve(true);
      return;
    }
    let params:any = assignParams(treeNode.dataRef, props.question.state.loadData);
    proxy.$Http.api(props.question.state.url, params, props.question.state.protType ? props.question.state.protType : 'get').then((res) => {
      if( res && res.data ){
        if( res.data.length ){
          treeNode.dataRef[fieldNames.value.children] = reData(res.data );
        }else{
          treeNode.dataRef.isLeaf = true;
        }
        props.question.options = [...props.question.options];
        resolve(true);
      }
    })
  });
}

function reData(list: any[]) {
  if( !list ){
    return []
  }
  return list.map((data: any) => {
    const item: any =  {...data, label: data[props.question.state.nameKey || fieldNames.value.title], value: data[props.question.state.nameValue || fieldNames.value.key]+''} ;
    //条件判断是否禁用
    if( Array.isArray(props.question.state.disabled)){
      item.disabled = isHidden(item, { showKey: props.question.state.disabled });
    }
    //判断是否异步加载
    if( props.question.state.loadData ){
      item.isLeaf = false;
    }
    if (data[props.question.state.nameChildren || fieldNames.value.children] && data[props.question.state.nameChildren || fieldNames.value.children].length > 0) {
      item.children = reData(data[props.question.state.nameChildren || fieldNames.value.children]);
    }
    return item;
  });
}


const init = () => {
  localValue.value = props.formData;
  selectAction();
  //获取参数

  //取配置信息
  if (props.question.type === 'dictionary') {
    if (props.question.state.url) {
      getDictionaryList(props.question.state, (res) => {
        props.question.options = res;
      });
      return;
    }
    let dicObj: any = dictionary[props.question.state.filterName] || localDictionary[props.question.state.filterName];
    let arr: any = [];
    for (const key in dicObj) {
      if (dicObj.hasOwnProperty(key)) {
        arr.push({
          label: dicObj[key],
          value: props.question.state.valueType === 'string' ? key + '' : +key
        });
      }
    }
    props.question.options = arr;
  } else if ((props.question.state.url && props.question.type !== 'search') || props.question.state.updateOption) {
    getOptions();
  } else if( props.question.state.labelInValue && localValue.value){
    localValue.value =  localValue.value.map((res)=>({
      key: res[props.question.state.labelInValue.value],
      label: res[props.question.state.labelInValue.label],
      value: res[props.question.state.labelInValue.value],
    }))
  }
};

//监听动态表单数据完成
const subWatch = () => {
  $subscribeSub = proxy.$NotificationFormSub
    .getParams()
    .pipe(filter((res: any) => res !== 0 && res.key !== RESETVERIFY))
    .subscribe((item: any) => {
      try {
        //联动同类型的初始化
        if (item.key == INITSERVE && item.value.initKeys.includes(props.question.key) ) {
          console.log('初始化数据', item);
          init();
        }
      } catch (error) {}
    });
};

const selectQs = (obj:any = { key:'', initState : false }) => {
  switch (obj.key) {
    default:
      proxy.$NotificationFormSub.pushParams({
        key: SELECTSERVE,
        value: {
          key: props.question.key,
          value: localValue.value,
          initState: obj.initState,
          data: state.data,
          index: props.index,
          name: props.question.state.name || ''
        }
      });
      break;
  }

  selectAction();

  //初始化服务
  if(!obj.initState && props.question.state.initKeys ){
    proxy.$NotificationFormSub.pushParams({
      key: INITSERVE,
      value: {
        initKeys: props.question.state.initKeys,
      }
    });
  }
  console.log('选中的值',obj.value );
 
  if( props.question.state.labelInValue ){
    let arr = [];
    if( props.question.type === 'tree' ){
      // let item = treeFindById(props.question.options, localValue.value, props.question.state.nameChildren);
      // if(item){
      //   arr = [item];
      // }
    }else{
      arr = props.question.options.filter((res)=>res.value === localValue.value);
      console.log('选中的数据',arr,props.question.options,localValue.value);
      if( arr && arr.length ){
        localValue.value  = arr.map((res:any)=>({
          key: res.key || res.value || res[props.question.state.labelInValue.value],
          [props.question.state.labelInValue.label]: res.label || res[props.question.state.labelInValue.label],
          [props.question.state.labelInValue.value]: res.value || res[props.question.state.labelInValue.value],
        }))
      }
    }
  }
  console.log('选中的值',localValue.value );
};
//选择灵动
const selectAction = () => {
  console.log('选择数据',);
  //控制form参数
  if (props.question.state && props.question.state.changeOptions) {
    // updateOptions(props.question.state.changeOptions[localValue.value] || props.question.state.changeOptions['default'])
  }
  //控制同行数据,自动赋值value  
  if( props.question.state.autoFillValue ){
    let data = props.question.options.find((res)=>res.value === localValue.value);
    autoValues(data, props.question.state.autoFillValue)
  }
  //选中后带上额外参数一起提交
  extendParams();
};

//自动填充值
const autoValues = (data,params)=>{
  for (const key in params) {
    if (data[params[key]] && data[params[key]] !== 0) {
      props.dataForm[key] = data[params[key]];
    }
  }
}

//扩展字段
const extendParams = ()=>{
  if( props.question.state.changeParams && localValue.value ){
    let data = props.question.options.find((res)=> typeof localValue.value === 'object'? localValue.value.includes(res.value): res.value === localValue.value);
    let params = paramsData(data,{params: props.question.state.changeParams});
    props.question.state.extendParams = Object.assign({},props.question.state.extendParams,params);
    console.log('看下参数',props.question.state);
  }
}

</script>

<style lang="less" scoped>
@import url('./input-select.component.less');
</style>
